﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;


namespace SharePointUtilitiesForDevelopers.Actions.Forms
{
  public partial class EventReceiversForm : Form
  {
    /// <summary>
    /// Actually loaded SPList
    /// </summary>
    private SPList _spList = null;

    /// <summary>
    /// Empty contructor of the form.
    /// </summary>
    public EventReceiversForm()
    {
      InitializeComponent();
    }

    /// <summary>
    /// URL of the selected site.
    /// </summary>
    public String WebUrl
    {
      get { return webUrlTextBox.Text; }
      set { webUrlTextBox.Text = value; }
    }

    /// <summary>
    /// String representing the GUID of the List. This string return the value 
    /// of the GUID textbox.
    /// </summary>
    public String ListGUID
    {
      get { return listNameTextBox.Text; }
      set { listNameTextBox.Text = value; }
    }

    /// <summary>
    /// Property which returns the actual SP List specified with given site url and
    /// GUID of the list. If the loaded list does not correspond to the GUID and site id
    /// the property fetches the desired one.
    /// </summary>
    public SPList ActualList
    {
      get
      {
        Guid listGUID = new Guid(this.ListGUID);
        if (_spList == null || _spList.ID != listGUID)
        {
          _spList = GetSPList(this.WebUrl, this.ListGUID);
        }

        return _spList;
      }
    }

    /// <summary>
    /// Method lists all the EventReceivers of the desired List in the ListBox.
    /// EventReceivers are represented in the listbox as "assembly>class"
    /// </summary>
    public void LoadReceivers()
    {
      //Clear the current list of receivers
      receiversListBox.Items.Clear();

      //SPList spList = GetSPList(this.WebUrl, this.ListName);
      try
      {
        for (int i = 0; i < this.ActualList.EventReceivers.Count; ++i)
        {
          SPEventReceiverDefinition erd = this.ActualList.EventReceivers[i];
          if (erd.Assembly != String.Empty && erd.Class != String.Empty)
          {
            receiversListBox.Items.Add(erd.Assembly + ">" + erd.Class);
          }
        }
      }
      catch (Exception ex)
      {
        //in case of problem I will let the Error
        throw new Exception(string.Format(Properties.Resources.ErrorWhileLoadingReceivers, this.ListGUID, this.WebUrl, ex.Message));
      }
    }

    /// <summary>
    /// Handles the change of index selection on the list of event receivers.
    /// Just loades the actual assembly and class name to the textbox.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Receivers_SelectedIndexChanged(object sender, EventArgs e)
    {
      string receiverDescription = receiversListBox.SelectedItem as String;
      char[] separator = { '>' };
      string[] receiverInfo = receiverDescription.Split(separator);
      assemblyTextBox.Text = receiverInfo[0];
      classTextBox.Text = receiverInfo[1];
    }

    /// <summary>
    /// Fetches list from the site by the url and GUID.
    /// </summary>
    /// <param name="siteUrl"></param>
    /// <param name="listGUID"></param>
    /// <returns></returns>
    private SPList GetSPList(String siteUrl, String listGUID)
    {
      using (SPSite lSite = new SPSite(this.WebUrl))
      {
        using (SPWeb lWeb = lSite.OpenWeb())
        {
          Guid listGuid = new Guid(this.ListGUID);

          SPList lList = lWeb.Lists[listGuid];
          return lList;
        }
      }
    }

    /// <summary>
    /// Removes desired EventReceiver from actually loaded list,
    /// if the receiver has been found on the list.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void removeButton_Click(object sender, EventArgs e)
    {
      string assemblyName = assemblyTextBox.Text;
      string className = classTextBox.Text;

      try
      {
        bool found = false;
        //Remove the old event recievers
        SPEventReceiverDefinition erd = null;
        //iterate through all item recievers
        //cannot use foreach because the collection gets modified after
        //delete of item
        for (int i = 0; i < this.ActualList.EventReceivers.Count; ++i)
        {
          erd = this.ActualList.EventReceivers[i];
          if (erd.Assembly == assemblyName && erd.Class == className)
          {
            found = true;
            break;
          }
        }

        if (found)
        {
          erd.Delete();
          MessageBox.Show(
                    this,
                    string.Format(Properties.Resources.ReceiverRemoved, className),
                    Properties.Resources.ReceiverRemovedCaption,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
        }
        else
        {
          MessageBox.Show(
                    this,
                    string.Format(Properties.Resources.ReceiverNotFound, className),
                    Properties.Resources.ReceiverNotFoundCaption,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
        }
      }
      catch (Exception ex)
      {
        throw new Exception(string.Format(Properties.Resources.ErrorWhileRemovingReceiver, className) + "\n" + ex.Message);
      }
      LoadReceivers();
    }

    /// <summary>
    /// Adds the EventReceiver specified by assembly and class to the specified list.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void addButton_Click(object sender, EventArgs e)
    {
      string assemblyName = assemblyTextBox.Text;
      string className = classTextBox.Text;

      try
      {
        this.ActualList.EventReceivers.Add(SPEventReceiverType.ItemAdded, assemblyName, className);
        MessageBox.Show(
                    this,
                    string.Format(Properties.Resources.ReceiverAdded, className),
                    Properties.Resources.ReceiverAddedCaption,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
      }
      catch (InvalidOperationException ex)
      {
           MessageBox.Show(
                    this,
                    string.Format(Properties.Resources.ErrorWhileAddingReceiver, className),
                    Properties.Resources.ErrorWhileAddingReceiverCaption,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
      }
      catch (Exception ex)
      {
        throw new Exception(string.Format(Properties.Resources.ErrorWhileAddingReceiver, className) + "\n" + ex.Message);
      }
      //reload the items in listbox
      LoadReceivers();
    }
  }
}
